import 'package:flutter/foundation.dart';
import 'package:logger/logger.dart';
import 'package:stack_trace/stack_trace.dart';

class LogUtils {
  static bool isDebug = !kReleaseMode;

  static Logger logger = Logger(printer: PrettyPrinter(methodCount: 0));

  ///过滤包名
  static bool _stackTraceFilter(Frame f) {
    return [
      'winkai',
      'winkai',
    ].contains(f.package);
  }

  static String _formatDateToStr(DateTime date, [String? rule]) {
    DateTime currentTime = date;
    int year = currentTime.year;
    int month = currentTime.month;
    int day = currentTime.day;
    int hour = currentTime.hour;
    int minute = currentTime.minute;
    int second = currentTime.second;
    format(int val) => '${val > 9 ? '' : '0'}$val';
    return (rule ?? 'yyyy-MM-dd')
        .replaceAll(RegExp(r'yyyy'), format(year))
        .replaceAll(RegExp(r'MM'), format(month))
        .replaceAll(RegExp(r'dd'), format(day))
        .replaceAll(RegExp(r'hh'), format(hour))
        .replaceAll(RegExp(r'mm'), format(minute))
        .replaceAll(RegExp(r'ss'), format(second));
  }

  /// 格式化日志
  static String _format(dynamic message, [StackTrace? stack]) {
    /// 格式化调用栈，仅保留当前包的调用栈信息, 需要注意取当前执行调用栈仅取两级，异常日志应当传入调用栈而非使用日志内部自动获取的调用栈信息
    String line;
    final timeStr = _formatDateToStr(DateTime.now(), 'yyyy-MM-dd hh:mm:ss');
    if (stack != null) {
      String stackTrace =
          Trace.format(Trace.from(stack).foldFrames(_stackTraceFilter));
      line = '[$timeStr]\n$message\n$stackTrace  \n';
    } else {
      line = '[$timeStr]\n$message  \n';
    }

    return line;
  }

  static void d(dynamic message, [StackTrace? stack]) {
    var value = _format(message);
    if (isDebug) {
      logger.d(value);
    }
  }

  static void e(dynamic message, [StackTrace? stack]) {
    var value = _format(message, stack);
    if (isDebug) {
      logger.e(value);
    }
  }

  static void v(dynamic message, [StackTrace? stack]) {
    var value = _format(message, stack);
    if (isDebug) {
      logger.v(value);
    }
  }

  static void i(dynamic message, [StackTrace? stack]) {
    var value = _format(message, stack);
    if (isDebug) {
      logger.i(value);
    }
  }

  static void w(dynamic message, [StackTrace? stack]) {
    var value = _format(message, stack);
    if (isDebug) {
      logger.w(value);
    }
  }

  static void wtf(dynamic message, [StackTrace? stack]) {
    var value = _format(message, stack);
    if (isDebug) {
      logger.wtf(value);
    }
  }
}
